home *** CD-ROM | disk | FTP | other *** search
- ; SHARDMEM.ASM
- ;
- ; This TSR sets aside a 64K shared memory region for other processes to use.
- ;
- ; Usage:
- ;
- ; SHARDMEM - Loads resident portion and activates
- ; shared memory capabilities.
- ;
- ; SHARDMEM REMOVE - Removes shared memory TSR from memory.
- ;
- ; This TSR checks to make sure there isn't a copy already active in
- ; memory. When removing itself from memory, it makes sure there are
- ; no other interrupts chained into INT 2Fh before doing the remove.
- ;
- ;
- ;
- ; The following segments must appear in this order and before the
- ; Standard Library includes.
-
- ResidentSeg segment para public 'Resident'
- ResidentSeg ends
-
- SharedMemory segment para public 'Shared'
- SharedMemory ends
-
- EndResident segment para public 'EndRes'
- EndResident ends
-
- .xlist
- .286
- include stdlib.a
- includelib stdlib.lib
- .list
-
-
- ; Resident segment that holds the TSR code:
-
- ResidentSeg segment para public 'Resident'
- assume cs:ResidentSeg, ds:nothing
-
- ; Int 2Fh ID number for this TSR:
-
- MyTSRID byte 0
- byte 0 ;Padding so we can print it.
-
- ; PSP is the psp address for this program.
-
- PSP word 0
-
- OldInt2F dword ?
-
-
- ; MyInt2F- Provides int 2Fh (multiplex interrupt) support for this
- ; TSR. The multiplex interrupt recognizes the following
- ; subfunctions (passed in AL):
- ;
- ; 00h- Verify presence. Returns 0FFh in AL and a pointer
- ; to an ID string in es:di if the
- ; TSR ID (in AH) matches this
- ; particular TSR.
- ;
- ; 01h- Remove. Removes the TSR from memory.
- ; Returns 0 in AL if successful,
- ; 1 in AL if failure.
- ;
- ; 10h- Return Seg Adrs. Returns the segment address of the
- ; shared segment in ES.
-
- MyInt2F proc far
- assume ds:nothing
-
- cmp ah, MyTSRID ;Match our TSR identifier?
- je YepItsOurs
- jmp OldInt2F
-
- ; Okay, we know this is our ID, now check for a verify, remove, or
- ; return segment call.
-
- YepItsOurs: cmp al, 0 ;Verify Call
- jne TryRmv
- mov al, 0ffh ;Return success.
- lesi IDString
- iret ;Return back to caller.
-
- IDString byte "Static Shared Memory TSR",0
-
- TryRmv: cmp al, 1 ;Remove call.
- jne TryRetSeg
-
- ; See if we can remove this TSR:
-
- push es
- mov ax, 0
- mov es, ax
- cmp word ptr es:[2Fh*4], offset MyInt2F
- jne TRDone
- cmp word ptr es:[2Fh*4 + 2], seg MyInt2F
- je CanRemove ;Branch if we can.
- TRDone: mov ax, 1 ;Return failure for now.
- pop es
- iret
-
- ; Okay, they want to remove this guy *and* we can remove it from memory.
- ; Take care of all that here.
-
- assume ds:ResidentSeg
-
- CanRemove: push ds
- pusha
- cli ;Turn off the interrupts while
- mov ax, 0 ; we mess with the interrupt
- mov es, ax ; vectors.
- mov ax, cs
- mov ds, ax
-
- mov ax, word ptr OldInt2F
- mov es:[2Fh*4], ax
- mov ax, word ptr OldInt2F+2
- mov es:[2Fh*4 + 2], ax
-
-
- ; Okay, one last thing before we quit- Let's give the memory allocated
- ; to this TSR back to DOS.
-
- mov ds, PSP
- mov es, ds:[2Ch] ;Ptr to environment block.
- mov ah, 49h ;DOS release memory call.
- int 21h
-
- mov ax, ds ;Release program code space.
- mov es, ax
- mov ah, 49h
- int 21h
-
- popa
- pop ds
- pop es
- mov ax, 0 ;Return Success.
- iret
-
- ; See if they want us to return the segment address of our shared segment
- ; here.
-
- TryRetSeg: cmp al, 10h ;Return Segment Opcode
- jne IllegalOp
- mov ax, SharedMemory
- mov es, ax
- mov ax, 0 ;Return success
- clc
- iret
-
- ; They called us with an illegal subfunction value. Try to do as little
- ; damage as possible.
-
- IllegalOp: mov ax, 0 ;Who knows what they were thinking?
- iret
- MyInt2F endp
- assume ds:nothing
- ResidentSeg ends
-
-
- ; Here's the segment that will actually hold the shared data.
-
- SharedMemory segment para public 'Shared'
- db 0FFFFh dup (?)
- SharedMemory ends
-
-
-
-
-
-
- cseg segment para public 'code'
- assume cs:cseg, ds:ResidentSeg
-
- ; SeeIfPresent- Checks to see if our TSR is already present in memory.
- ; Sets the zero flag if it is, clears the zero flag if
- ; it is not.
-
- SeeIfPresent proc near
- push es
- push ds
- push di
- mov cx, 0ffh ;Start with ID 0FFh.
- IDLoop: mov ah, cl
- push cx
- mov al, 0 ;Verify presence call.
- int 2Fh
- pop cx
- cmp al, 0 ;Present in memory?
- je TryNext
- strcmpl
- byte "Static Shared Memory TSR",0
- je Success
-
- TryNext: dec cl ;Test USER IDs of 80h..FFh
- js IDLoop
- cmp cx, 0 ;Clear zero flag.
- Success: pop di
- pop ds
- pop es
- ret
- SeeIfPresent endp
-
-
-
- ; FindID- Determines the first (well, last actually) TSR ID available
- ; in the multiplex interrupt chain. Returns this value in
- ; the CL register.
- ;
- ; Returns the zero flag set if it locates an empty slot.
- ; Returns the zero flag clear if failure.
-
- FindID proc near
- push es
- push ds
- push di
-
- mov cx, 0ffh ;Start with ID 0FFh.
- IDLoop: mov ah, cl
- push cx
- mov al, 0 ;Verify presence call.
- int 2Fh
- pop cx
- cmp al, 0 ;Present in memory?
- je Success
- dec cl ;Test USER IDs of 80h..FFh
- js IDLoop
- xor cx, cx
- cmp cx, 1 ;Clear zero flag
- Success: pop di
- pop ds
- pop es
- ret
- FindID endp
-
-
-
- Main proc
- meminit
-
- mov ax, ResidentSeg
- mov ds, ax
-
- mov ah, 62h ;Get this program's PSP
- int 21h ; value.
- mov PSP, bx
-
- ; Before we do anything else, we need to check the command line
- ; parameters. If there is one, and it is the word "REMOVE", then remove
- ; the resident copy from memory using the multiplex (2Fh) interrupt.
-
- argc
- cmp cx, 1 ;Must have 0 or 1 parms.
- jb TstPresent
- je DoRemove
- Usage: print
- byte "Usage:",cr,lf
- byte " shardmem",cr,lf
- byte "or shardmem REMOVE",cr,lf,0
- ExitPgm
-
-
- ; Check for the REMOVE command.
-
- DoRemove: mov ax, 1
- argv
- stricmpl
- byte "REMOVE",0
- jne Usage
-
- call SeeIfPresent
- je RemoveIt
- print
- byte "TSR is not present in memory, cannot remove"
- byte cr,lf,0
- ExitPgm
-
- RemoveIt: mov MyTSRID, cl
- printf
- byte "Removing TSR (ID #%d) from memory...",0
- dword MyTSRID
-
- mov ah, cl
- mov al, 1 ;Remove cmd, ah contains ID
- int 2Fh
- cmp al, 1 ;Succeed?
- je RmvFailure
- print
- byte "removed.",cr,lf,0
- ExitPgm
-
- RmvFailure: print
- byte cr,lf
- byte "Could not remove TSR from memory.",cr,lf
- byte "Try removing other TSRs in the reverse order "
- byte "you installed them.",cr,lf,0
- ExitPgm
-
-
-
- ; Okay, see if the TSR is already in memory. If so, abort the
- ; installation process.
-
- TstPresent: call SeeIfPresent
- jne GetTSRID
- print
- byte "TSR is already present in memory.",cr,lf
- byte "Aborting installation process",cr,lf,0
- ExitPgm
-
-
- ; Get an ID for our TSR and save it away.
-
- GetTSRID: call FindID
- je GetFileName
- print
- byte "Too many resident TSRs, cannot install",cr,lf,0
- ExitPgm
-
-
- ; Things look cool so far, so install the interrupts
-
- GetFileName: mov MyTSRID, cl
- print
- byte "Installing interrupts...",0
-
-
- ; Patch into the INT 2Fh interrupt chain.
-
- cli ;Turn off interrupts!
- mov ax, 0
- mov es, ax
- mov ax, es:[2Fh*4]
- mov word ptr OldInt2F, ax
- mov ax, es:[2Fh*4 + 2]
- mov word ptr OldInt2F+2, ax
- mov es:[2Fh*4], offset MyInt2F
- mov es:[2Fh*4+2], seg ResidentSeg
- sti ;Okay, ints back on.
-
- ; We're hooked up, the only thing that remains is to zero out the shared
- ; memory segment and then terminate and stay resident.
-
- printf
- byte "Installed, TSR ID #%d.",cr,lf,0
- dword MyTSRID
-
- mov ax, SharedMemory ;Zero out the shared
- mov es, ax ; memory segment.
- mov cx, 32768
- xor ax, ax
- mov di, ax
- rep stosw
-
-
- mov dx, EndResident ;Compute size of program.
- sub dx, PSP
- mov ax, 3100h ;DOS TSR command.
- int 21h
- Main endp
- cseg ends
-
- sseg segment para stack 'stack'
- stk db 256 dup (?)
- sseg ends
-
- zzzzzzseg segment para public 'zzzzzz'
- LastBytes db 16 dup (?)
- zzzzzzseg ends
- end Main
-